package org.sn.jdish.interview.thoughtworks.purchase;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.List;

/**
 * 商品业务处理
 */
public class MerchandiseService {

	/**
	 * 数据环境初始化
	 * 
	 * @throws Exception
	 */
	public static void init() throws Exception {
		MerchandiseDao.init();
	}

	/**
	 * 数据解析和数据录入
	 * 
	 * @param merchandiseFile
	 * @throws Exception
	 */
	public static void record(String merchandiseFile) throws Exception {
		FileReader fr = new FileReader(merchandiseFile);
		BufferedReader br = new BufferedReader(fr);
		String line = "";
		String[] merchandiseInfos = null;
		while ((line = br.readLine()) != null) {
			merchandiseInfos = line.split("\\s");
			switch (merchandiseInfos[1]) {
			case "NEW":
				saveNewMerchandise(MerchandiseUtil.convet2NewMerchandise(merchandiseInfos));
				break;
			case "PURCHASE":
				savePurchaseMerchandise(MerchandiseUtil.convet2PurchaseMerchandise(merchandiseInfos));
				break;
			case "SALES":
				saveSalesMerchandise(MerchandiseUtil.convet2SalesMerchandise(merchandiseInfos));
				break;
			default:
				System.out.println("Failed to parse: " + line);
			}
		}
		br.close();
		fr.close();
	}

	/**
	 * 保存引入商品
	 * 
	 * @param newMerchandise
	 * @throws Exception
	 */
	private static void saveNewMerchandise(Merchandise newMerchandise) throws Exception {
		if (MerchandiseDao.noNewMerchandise(newMerchandise)) {
			MerchandiseDao.saveNewMerchandise(newMerchandise);
		}
	}

	/**
	 * 保存采购商品
	 * 
	 * @param purchaseMerchandise
	 * @throws Exception
	 */
	private static void savePurchaseMerchandise(Merchandise purchaseMerchandise) throws Exception {
		if (MerchandiseDao.getNewMerchandise(purchaseMerchandise.getBarCode()) == null) {
			System.out.println("Did not found merchandise with barcode euqals " + purchaseMerchandise.getBarCode());
			return;
		}
		if (MerchandiseDao.noPurchaseMerchandise(purchaseMerchandise)) {
			MerchandiseDao.savePurchaseMerchandise(purchaseMerchandise);
		}
	}

	/**
	 * 保存销售商品
	 * 
	 * @param salesMerchandise
	 * @throws Exception
	 */
	private static void saveSalesMerchandise(Merchandise salesMerchandise) throws Exception {
		if (MerchandiseDao.getNewMerchandise(salesMerchandise.getBarCode()) == null) {
			System.out.println("Did not found merchandise with barcode euqals " + salesMerchandise.getBarCode());
			return;
		}
		if (MerchandiseDao.noSalesMerchandise(salesMerchandise)) {
			if (getInventoryQuantity(salesMerchandise.getBarCode()) < salesMerchandise.getSalesNum()) {
				System.out.println("Do not have enough merchandise " + salesMerchandise.getBarCode());
				return;
			}
			MerchandiseDao.saveSalesMerchandise(salesMerchandise);
		}
	}

	/**
	 * 生成报表
	 * 
	 * @throws Exception
	 */
	public static void genReport() throws Exception {
		StringBuilder outputReport = new StringBuilder();
		List<Merchandise> newMerchandiseList = MerchandiseDao.getNewMerchandiseList();
		for (Merchandise newMerchandise : newMerchandiseList) {
			outputReport.append(MerchandiseUtil.output(newMerchandise.getName(),
					getInventoryQuantity(newMerchandise.getBarCode()), getInventoryAmount(newMerchandise.getBarCode()),
					getSalesQuantity(newMerchandise.getBarCode()),
					getSalesAmount(newMerchandise.getBarCode(), newMerchandise.getPrice()),
					getProfit(newMerchandise.getBarCode(), newMerchandise.getPrice())));
		}
		System.out.println(outputReport.toString());
		MerchandiseDao.saveReport(outputReport.toString());
	}

	/**
	 * 库存数量
	 * 
	 * @param barCode
	 * @return
	 * @throws Exception
	 */
	private static int getInventoryQuantity(String barCode) throws Exception {
		int inventoryQuantity = 0;
		List<Merchandise> purchaseMerchandiseList = MerchandiseDao.getPurchaseMerchandiseList();
		for (Merchandise purchaseMerchandise : purchaseMerchandiseList) {
			if (purchaseMerchandise.getBarCode().equals(barCode)) {
				inventoryQuantity += purchaseMerchandise.getPurchaseNum();
			}
		}
		inventoryQuantity -= getSalesQuantity(barCode);
		return inventoryQuantity;
	}

	/**
	 * 销售数量
	 * 
	 * @param barCode
	 * @return
	 * @throws Exception
	 */
	private static int getSalesQuantity(String barCode) throws Exception {
		int salesQuantity = 0;
		List<Merchandise> salesMerchandiseList = MerchandiseDao.getSalesMerchandiseList();
		for (Merchandise salesMerchandise : salesMerchandiseList) {
			if (salesMerchandise.getBarCode().equals(barCode)) {
				salesQuantity += salesMerchandise.getSalesNum();
			}
		}
		return salesQuantity;
	}

	/**
	 * 库存金额
	 * 
	 * @param barCode
	 * @return
	 * @throws Exception
	 */
	private static double getInventoryAmount(String barCode) throws Exception {
		double inventoryAmount = 0;
		int salesQuantity = getSalesQuantity(barCode);
		if (getInventoryQuantity(barCode) > 0) {
			List<Merchandise> purchaseMerchandiseList = MerchandiseDao.getPurchaseMerchandiseList();
			for (Merchandise purchaseMerchandise : purchaseMerchandiseList) {
				if (purchaseMerchandise.getBarCode().equals(barCode)) {
					if (purchaseMerchandise.getPurchaseNum() > salesQuantity) {
						inventoryAmount += (purchaseMerchandise.getPurchaseNum() - salesQuantity)
								* purchaseMerchandise.getPurchasePrice();
					} else {
						salesQuantity -= purchaseMerchandise.getPurchaseNum();
					}
				}
			}
		}
		return inventoryAmount;
	}

	/**
	 * 销售金额
	 * 
	 * @param barCode
	 * @param price
	 * @return
	 * @throws Exception
	 */
	private static double getSalesAmount(String barCode, double price) throws Exception {
		return getSalesQuantity(barCode) * price;
	}

	/**
	 * 销售利润
	 * 
	 * @param barCode
	 * @param price
	 * @return
	 * @throws Exception
	 */
	private static double getProfit(String barCode, double price) throws Exception {
		double profit = getSalesAmount(barCode, price);
		int salesQuantity = getSalesQuantity(barCode);
		List<Merchandise> purchaseMerchandiseList = MerchandiseDao.getPurchaseMerchandiseList();
		for (Merchandise purchaseMerchandise : purchaseMerchandiseList) {
			if (purchaseMerchandise.getBarCode().equals(barCode)) {
				if (purchaseMerchandise.getPurchaseNum() < salesQuantity) {
					profit -= purchaseMerchandise.getPurchaseNum() * purchaseMerchandise.getPurchasePrice();
					salesQuantity -= purchaseMerchandise.getPurchaseNum();
				} else {
					profit -= salesQuantity * purchaseMerchandise.getPurchasePrice();
					break;
				}
			}
		}
		return profit;
	}

}
